<?php

namespace App\Http\Controller\Test;

use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
use Swoft\Http\Server\Annotation\Mapping\RequestMethod;
use Swoft\Redis\Redis;

/**
 * Class Consul
 * @Controller(prefix="/Redis")
 */
class SwoftRedisController extends BaseController {

    /**
     * @RequestMapping(route="set",method={RequestMethod::GET})
     */
    public function set(){
        return Redis::set('apple','www.apple.com');
    }

    /**
     * @RequestMapping(route="get",method={RequestMethod::GET})
     */
    public function get(){
        return Redis::get('apple');
    }

    /**
     * @RequestMapping(route="h_set",method={RequestMethod::GET})
     */
    public function hSet(){
        return Redis::hSet('website','google','www.google.com');
    }

    /**
     * @RequestMapping(route="h_get",method={RequestMethod::GET})
     */
    public function hGet(){
        return Redis::hGet('website','google');
    }

    /**
     * @RequestMapping(route="h_mset",method={RequestMethod::GET})
     */
    public function hMset(){
        $websites = [
            'sina' => 'www.sina.com.cn',
            'baidu' => 'www.baidu.com'
        ];
        return Redis::hMset('website',$websites);
    }

    /**
     * @RequestMapping(route="h_mget",method={RequestMethod::GET})
     */
    public function hMget(){
        return Redis::hMget('website',['baidu','google']);
    }

    /**************************实际应用****************************/
    /**
     * 队列操作，队列存放10条商品记录，每次插入一条新记录就会删除掉一条最老的记录
     * @RequestMapping(route="queue_in",method={RequestMethod::GET})
     */
    public function queueIn(){
        //$data 模拟从数据库中查询出的数据
        $data = [
            'id' => rand(1,9999),
            'goods_name' => '商品'.rand(0,99999),
            'create_time' => date('Y-m-d')
        ];
        Redis::lPush('goods',$data);
        Redis::lTrim('goods',0,9);
        $goods = array();
        foreach(Redis::lRange('goods',0,9) as $item){
            $goods[] = $item;
        }
        return $goods;
    }

    /**
     * 图片点赞，如果redis中存在该图片记录，则对应的赞 +1，如不存在则从数据库中查出然后存入redis
     * @RequestMapping(route="thumb/{id}",method={RequestMethod::GET})
     */
    public function thumb($id){
        if(Redis::exists('img_'.$id)){
            Redis::hIncrBy('img_'.$id,'img_prise',1);
        }else{
            //$data 模拟从数据库中查询出的数据
            $data = [
                'img_id' => $id,
                'img_prise' => rand(1,999),
                'img_url' => md5(rand(999,99999))
            ];
            Redis::hMset('img_'.$id,$data);
        }
        return Redis::hMget('img_'.$id, ['img_id','img_prise','img_url']);
    }

    /**
     * @RequestMapping(route="pool_set",method={RequestMethod::GET})
     */
    public function poolSet()
    {
        $key   = 'key';
        $value = uniqid();

        $this->redis->set($key, $value);

        $get = $this->redis->get($key);

        return [$get, $value];
    }

    /**
     * @RequestMapping(route="zadd",method={RequestMethod::GET})
     */
    public function zAdd()
    {
        $key = 'key1';

        $data = [
            'add'    => 11.1,
            'score2' => 11.1,
            'score3' => 11.21
        ];
        $this->redis->zAdd($key, $data);

        $res = Redis::zRangeByScore($key, '11.1', '11.21', ['withscores' => true]);

        return [$res, $res === $data];
    }

    /**
     * @RequestMapping(route="str",method={RequestMethod::GET})
     */
    public function str()
    {
        $key    = 'key';
        $result = Redis::set($key, 'key');

        $keyVal = Redis::get($key);

        $isError = Redis::call(function (\Redis $redis) {
            $redis->eval('return 1');

            return $redis->getLastError();
        });

        $data = [
            $result,
            $keyVal,
            $isError
        ];

        return $data;
    }

    /**
     * Only to use test. The wrong way to use it
     *
     * @RequestMapping(route="release",method={RequestMethod::GET})
     *
     * @return array
     * @throws RedisException
     */
    public function release()
    {
        sgo(function () {
            Redis::connection();
        });

        Redis::connection();

        return ['release'];
    }

    /**
     * Only to use test. The wrong way to use it
     *
     * @RequestMapping(route="ex_pipeline",method={RequestMethod::GET})
     *
     * @return array
     */
    public function exPipeline()
    {
        sgo(function () {
            Redis::pipeline(function () {
                throw new RuntimeException('');
            });
        });

        Redis::pipeline(function () {
            throw new RuntimeException('');
        });

        return ['exPipeline'];
    }

    /**
     * Only to use test. The wrong way to use it
     *
     * @RequestMapping(route="ex_transaction",method={RequestMethod::GET})
     *
     * @return array
     */
    public function exTransaction()
    {
        sgo(function () {
            Redis::transaction(function () {
                throw new RuntimeException('');
            });
        });

        Redis::transaction(function () {
            throw new RuntimeException('');
        });

        return ['exPipeline'];
    }
}